package com.osce.score.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.csce.domain.entity.score.ScoreExExamMark;
import com.csce.domain.entity.score.ScoreExExamPlaceAllot;
import com.csce.domain.entity.score.ScoreExExamScore;
import com.csce.domain.entity.score.ScoreExExamSession;
import com.csce.domain.entity.score.dto.ScoreSheetStepDto;
import com.csce.domain.entity.score.socket.ExPlacePeoPleVo;
import com.csce.domain.entity.score.socket.WaitingPeoPleVo;
import com.doudou.core.container.ListUtil;
import com.doudou.core.lang.ObjUtil;
import com.doudou.core.number.DecimalUtil;
import com.doudou.core.throwable.GlobalException;
import com.osce.common.core.entity.model.LoginUser;
import com.osce.interfaces.score.IScoreExExamPlaceAllotService;
import com.osce.interfaces.score.IScoreExExamScoreService;
import com.osce.interfaces.score.IScoreExExamSessionService;
import com.osce.score.mapper.ScoreExExamMarkMapper;
import com.osce.score.mapper.ScoreExExamScoreMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 考试Service业务层处理
 *
 * @author zzx
 * @since 2023-09-05
 */
@Service
public class ScoreExExamScoreServiceImpl implements IScoreExExamScoreService {

    @Resource private IScoreExExamPlaceAllotService exExamPlaceAllotService;

    @Resource private ScoreExExamMarkMapper scoreExExamMarkMapper;

    @Resource private ScoreExExamScoreMapper scoreExExamScoreMapper;

    @Resource private IScoreExExamSessionService sessionService;

    /**
     * 打分
     */
    @Override
    @Transactional
    public ExPlacePeoPleVo saveMark(JSONObject request, LoginUser examiner, WaitingPeoPleVo peoPleVo) throws Exception {
        ExPlacePeoPleVo result = new ExPlacePeoPleVo();
        String code = request.getStr("code");//学生代号
        Long sheetId = request.getLong("sheetId");
        Long sessionId = request.getLong("sessionId");
        String comment = request.getStr("comment");//点评
        Long userId = peoPleVo.getUserId();
        result.setCode(code);
        result.setUserId(userId);
        result.setSheetId(sheetId);
        if (ObjUtil.isEmpty(userId)) {
            throw new GlobalException("打分失败，学员代号或学员编号有误");
        }
        Long examIdL = request.getLong("examId");
        Long timeIdL = request.getLong("timeId");
        Long placeIdL = request.getLong("placeId");
        //根据考试节次查询考场安排
        List<ScoreExExamPlaceAllot> placeAllots = exExamPlaceAllotService.selectScoreExExamPlaceAllotList(ScoreExExamPlaceAllot.builder().examId(examIdL).code(code).sessionId(sessionId).sheetId(sheetId).build());
        if (ListUtil.isEmpty(placeAllots)) {
            throw new GlobalException("打分失败，未查询到考场安排");
        }
        ScoreExExamPlaceAllot exExamPlaceAllot = placeAllots.get(0);
        result.setAllotId(exExamPlaceAllot.getId());
        //重置分数列表
        List<ScoreSheetStepDto> score = request.getBeanList("data", ScoreSheetStepDto.class);//分数列表
        BigDecimal total = ListUtil.sumDecimalByKey(score, "mark");//总分
        String examinerType = getExaminerType(sessionId, examiner.getUserId());
        result.setExaminerType(examinerType);
        result.setExaminerId(examiner.getUserId());
        //修改考试安排考试学员id、状态、打分时间
        exExamPlaceAllotService.updateScoreExExamPlaceAllot(ScoreExExamPlaceAllot.builder().id(exExamPlaceAllot.getId()).
                exUserId(userId).status(2).reservedOne(DateUtil.now()).build());
        ScoreExExamMark scoreExExamMark = new ScoreExExamMark(null, examIdL, timeIdL, placeIdL, sessionId, exExamPlaceAllot.getId(), userId, sheetId, getExaminerType(sessionId, examiner.getUserId()), total,comment,null);
        scoreExExamMark.setCreateBy(examiner.getUserId()+"");
        scoreExExamMark.setCreateTime(DateUtil.date());
        List<ScoreExExamScore> scoreList = score.stream().map(stepDto -> new ScoreExExamScore(null, stepDto.getId(), stepDto.getMark())).collect(Collectors.toList());
        result.setScore(insertScoreExExamMark(scoreExExamMark,scoreList) > 0 ? total : DecimalUtil.newDecimal("-1"));
        return result;
    }

    @Transactional
    public int insertScoreExExamMark(ScoreExExamMark scoreExExamMark,List<ScoreExExamScore> scoreList) {
        //先删除之前的记录
        ScoreExExamMark selectMark = scoreExExamMarkMapper.selectScoreExExamMark(scoreExExamMark);
        if (ObjUtil.isNotNull(selectMark)){
            scoreExExamScoreMapper.deleteScoreExExamScoreByMarkId(selectMark.getId());
            scoreExExamMarkMapper.deleteScoreExExamMarkById(selectMark.getId());
        }
        int i = scoreExExamMarkMapper.insertScoreExExamMark(scoreExExamMark);
        if (i > 0 && ListUtil.isNotEmpty(scoreList)){
            scoreExExamScoreMapper.batchInsertScoreExExamScore(scoreList,scoreExExamMark.getId());
        }
        return i;
    }

    @Override
    public Map<Long, ScoreExExamScore> selectScoreMapByMarkId(Long id) {
        return scoreExExamScoreMapper.selectScoreMapByMarkId(id);
    }

    @Override
    public Map<Long, ScoreExExamScore> getScoreExExamScoreMap(ScoreExExamPlaceAllot allot,Long examinerId) {
        ScoreExExamMark mark = scoreExExamMarkMapper.selectScoreExExamMarkByAllotAndUser(allot.getId(),allot.getSheetId(),allot.getExUserId(),examinerId);
        if (ObjUtil.isNull(mark)){
            return null;
        }
        return scoreExExamScoreMapper.selectScoreMapByMarkId(mark.getId());
    }

    private String getExaminerType(Long sessionId,Long userId){
        ScoreExExamSession session = sessionService.selectScoreExExamSessionById(sessionId);
        if (ObjUtil.isNotNull(session.getSceneExaminer()) && ObjUtil.equals(session.getSceneExaminer(), userId)){//现场
            return "1";
        }else if (ObjUtil.isNotNull(session.getCenterExaminer()) && ObjUtil.equals(session.getCenterExaminer(), userId)){//中控
            return "2";
        }else if (ObjUtil.isNotNull(session.getSshExaminer()) && ObjUtil.equals(session.getSshExaminer(), userId)){//远程
            return "3";
        }else {
            throw new GlobalException("您未分配该考场监考，请确认");
        }
    }
}

